package net.ib.mtalk.network.pipeline;

import static org.jboss.netty.buffer.ChannelBuffers.dynamicBuffer;

import java.nio.ByteOrder;

import net.ib.mntalk.protocol.Common.Envelope;
import net.ib.mtalk.util.MTalkLogWriter;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBufferOutputStream;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;

import android.os.PowerManager;

import com.google.protobuf.micro.CodedOutputStreamMicro;

/**
 * Envelope <-> ChannelBuffer<br>
 * @author Arngard
 */
public class EnvelopeBicoder extends OneToOneBicoder {
	
	private PowerManager.WakeLock mWakeLock; 
	
	public EnvelopeBicoder(PowerManager.WakeLock wakeLock) {
		this.mWakeLock = wakeLock;
	}
	
	@Override
	protected Object encode(ChannelHandlerContext ctx, Channel channel, Object object) throws Exception {
		MTalkLogWriter.v(this.getClass().getSimpleName()+".encode() - STT");
		
		if(mWakeLock != null) mWakeLock.acquire();
		try {
			Envelope envelop = (Envelope) object;
			ChannelBufferOutputStream bout = new ChannelBufferOutputStream(
					dynamicBuffer(ByteOrder.BIG_ENDIAN, envelop.getSerializedSize(), ctx.getChannel().getConfig().getBufferFactory()));
	
			CodedOutputStreamMicro cosm = CodedOutputStreamMicro.newInstance(bout);
			envelop.writeTo(cosm);
			cosm.flush();
	
			return bout.buffer();
		} finally {
			if(mWakeLock != null) mWakeLock.release();

			MTalkLogWriter.v(this.getClass().getSimpleName()+".encode() - END");
		}
	}
	
	@Override
	protected Object decode(ChannelHandlerContext ctx, Channel channel, Object object) throws Exception {
		MTalkLogWriter.v(this.getClass().getSimpleName()+".decode() - STT");

		if(mWakeLock != null) mWakeLock.acquire();
		try {
			ChannelBuffer buffer = (ChannelBuffer) object;
			return Envelope.parseFrom(buffer.array());
		} finally {
			if(mWakeLock != null) mWakeLock.release();

			MTalkLogWriter.v(this.getClass().getSimpleName()+".decode() - END");
		}
	}

}
